home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre1.z / postgre1 / test / postfs.usr.bin / mv.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-27  |  5.5 KB  |  294 lines

  1. /*
  2.  * Copyright (c) 1980 Regents of the University of California.
  3.  * All rights reserved.  The Berkeley software License Agreement
  4.  * specifies the terms and conditions for redistribution.
  5.  */
  6.  
  7. #ifndef lint
  8. char copyright[] =
  9. "@(#) Copyright (c) 1980 Regents of the University of California.\n\
  10.  All rights reserved.\n";
  11. #endif not lint
  12.  
  13. /*
  14.  * mv file1 file2
  15.  */
  16. #include <sys/param.h>
  17. #include <sys/stat.h>
  18. #include <sys/time.h>
  19.  
  20. #include <stdio.h>
  21. #include <sys/dir.h>
  22. #include <errno.h>
  23. #include <signal.h>
  24. #include "tmp/libpq-fs.h"
  25.  
  26. #define    DELIM    '/'
  27. #define MODEBITS 07777
  28.  
  29. #define    ISDIR(st)    (((st).st_mode&S_IFMT) == S_IFDIR)
  30. #define    ISLNK(st)    (((st).st_mode&S_IFMT) == S_IFLNK)
  31. #define    ISREG(st)    (((st).st_mode&S_IFMT) == S_IFREG)
  32. #define    ISDEV(st) \
  33.     (((st).st_mode&S_IFMT) == S_IFCHR || \
  34.      ((st).st_mode&S_IFMT) == S_IFBLK || \
  35.      ((st).st_mode&S_IFMT) == S_IFIFO)
  36.  
  37. char    *sprintf();
  38. char    *dname();
  39. struct    pgstat s1, s2;
  40. int    iflag = 0;    /* interactive mode */
  41. int    fflag = 0;    /* force overwriting */
  42. extern    int p_errno;
  43. extern char *getenv();
  44.  
  45. main(argc, argv)
  46.     register char *argv[];
  47. {
  48.     register i, r;
  49.     register char *arg;
  50.     char *dest;
  51.     char *dbname;
  52.  
  53.     if (argc < 2)
  54.         goto usage;
  55.  
  56.     if ((dbname = getenv("DATABASE")) == (char *) NULL) {
  57.         fprintf(stderr, "no database specified in env var DATABASE\n");
  58.         fflush(stderr);
  59.         exit (1);
  60.     }
  61.  
  62.     PQsetdb(dbname);
  63.  
  64.     while (argc > 1 && *argv[1] == '-') {
  65.         argc--;
  66.         arg = *++argv;
  67.  
  68.         /*
  69.          * all files following a null option
  70.          * are considered file names
  71.          */
  72.         if (*(arg+1) == '\0')
  73.             break;
  74.         while (*++arg != '\0') switch (*arg) {
  75.  
  76.         case 'i':
  77.             iflag++;
  78.             break;
  79.  
  80.         case 'f':
  81.             fflag++;
  82.             break;
  83.  
  84.         default:
  85.             goto usage;
  86.         }
  87.     }
  88.     if (argc < 3)
  89.         goto usage;
  90.     dest = argv[argc-1];
  91.     if (p_stat(dest, &s2) >= 0 && ISDIR(s2)) {
  92.         r = 0;
  93.         for (i = 1; i < argc-1; i++)
  94.             r |= movewithshortname(argv[i], dest);
  95.         exit(r);
  96.     }
  97.     if (argc > 3)
  98.         goto usage;
  99.     r = move(argv[1], argv[2]);
  100.     PQfinish();
  101.     exit(r);
  102.     /*NOTREACHED*/
  103. usage:
  104.     fprintf(stderr,
  105. "usage: mv [-if] f1 f2 or mv [-if] f1 ... fn d1 (`fn' is a file or directory)\n");
  106.     return (1);
  107. }
  108.  
  109. movewithshortname(src, dest)
  110.     char *src, *dest;
  111. {
  112.     register char *shortname;
  113.     char target[MAXPATHLEN + 1];
  114.  
  115.     shortname = dname(src);
  116.     if (strlen(dest) + strlen(shortname) > MAXPATHLEN - 1) {
  117.         error("%s/%s: pathname too long", dest,
  118.             shortname);
  119.         return (1);
  120.     }
  121.     sprintf(target, "%s/%s", dest, shortname);
  122.     return (move(src, target));
  123. }
  124.  
  125. move(source, target)
  126.     char *source, *target;
  127. {
  128.     int targetexists;
  129.  
  130.     if (p_stat(source, &s1) < 0) {
  131.         Perror2(source, "Cannot access");
  132.         return (1);
  133.     }
  134.     /*
  135.      * First, try to rename source to destination.
  136.      * The only reason we continue on failure is if
  137.      * the move is on a nondirectory and not across
  138.      * file systems.
  139.      */
  140.     targetexists = p_stat(target, &s2) >= 0;
  141.     if (targetexists) {
  142.         if (s1.st_ino == s2.st_ino) {
  143.             error("%s and %s are identical", source, target);
  144.             return (1);
  145.         }
  146.         if (iflag && !fflag && isatty(fileno(stdin)) &&
  147.             query("remove %s? ", target) == 0)
  148.             return (1);
  149. #if 0        
  150.         if (access(target, 2) < 0 && !fflag && isatty(fileno(stdin))) {
  151.             if (query("override protection %o for %s? ",
  152.               s2.st_mode & MODEBITS, target) == 0)
  153.                 return (1);
  154.         }
  155. #endif
  156.     }
  157.     if (p_rename(source, target) >= 0)
  158.         return (0);
  159.     Perror2(p_errno == PENOENT && targetexists == 0 ? target : source,
  160.             "rename");
  161.     return (1);
  162.  
  163. #if 0
  164.     if (targetexists && p_unlink(target) < 0) {
  165.         Perror2(target, "Cannot unlink");
  166.         return (1);
  167.     }
  168.     if (ISREG(s1)) {
  169.         register int fi, fo, n;
  170.         struct timeval tv[2];
  171.         char buf[MAXBSIZE];
  172.  
  173.         fi = p_open(source, 0);
  174.         if (fi < 0) {
  175.             Perror(source);
  176.             return (1);
  177.         }
  178.  
  179.         fo = p_creat(target, s1.st_mode & MODEBITS,Unix);
  180.         if (fo < 0) {
  181.             Perror(target);
  182.             p_close(fi);
  183.             return (1);
  184.         }
  185.  
  186.         for (;;) {
  187.             n = p_read(fi, buf, sizeof buf);
  188.             if (n == 0) {
  189.                 break;
  190.             } else if (n < 0) {
  191.                 Perror2(source, "p_read");
  192.                 p_close(fi);
  193.                 p_close(fo);
  194.                 return (1);
  195.             } else if (p_write(fo, buf, n) != n) {
  196.                 Perror2(target, "p_write");
  197.                 p_close(fi);
  198.                 p_close(fo);
  199.                 return (1);
  200.             }
  201.         }
  202.  
  203.         p_close(fi);
  204.         if (p_close(fo) < 0) {
  205.             Perror2(target, "p_write");
  206.             return (1);
  207.         }
  208. #if 0
  209.         tv[0].tv_sec = s1.st_atime;
  210.         tv[0].tv_usec = 0;
  211.         tv[1].tv_sec = s1.st_mtime;
  212.         tv[1].tv_usec = 0;
  213.         (void) utimes(target, tv); 
  214. #endif
  215.         goto cleanup;
  216.     }
  217.     error("%s: unknown file type %o", source, s1.st_mode);
  218.     return (1);
  219.  
  220. cleanup:
  221.     if (p_unlink(source) < 0) {
  222.         /*
  223.          * If the unlink failed because of ENOENT we will assume
  224.          * that somebody rm'ed the file before we got a chance
  225.          * to do it.  So just report the failure but leave the
  226.          * target there.  Also, don't remove target when target
  227.          * existed previously.
  228.          */
  229.         if (p_errno == PENOENT || targetexists)
  230.             Perror2(source, "Cannot unlink");
  231.         else  {
  232.             (void) p_unlink(target);
  233.             Perror2(source, "Cannot unlink");
  234.         }
  235.         return (1);
  236.     }
  237.     return (0);
  238. #endif
  239. }
  240.  
  241. /*VARARGS*/
  242. query(prompt, a1, a2)
  243.     char *a1;
  244. {
  245.     register int i, c;
  246.  
  247.     fprintf(stderr, prompt, a1, a2);
  248.     i = c = getchar();
  249.     while (c != '\n' && c != EOF)
  250.         c = getchar();
  251.     return (i == 'y');
  252. }
  253.  
  254. char *
  255. dname(name)
  256.     register char *name;
  257. {
  258.     register char *p;
  259.  
  260.     p = name;
  261.     while (*p)
  262.         if (*p++ == DELIM && *p)
  263.             name = p;
  264.     return name;
  265. }
  266.  
  267. /*VARARGS*/
  268. error(fmt, a1, a2)
  269.     char *fmt;
  270. {
  271.  
  272.     fprintf(stderr, "mv: ");
  273.     fprintf(stderr, fmt, a1, a2);
  274.     fprintf(stderr, "\n");
  275. }
  276.  
  277. Perror(s)
  278.     char *s;
  279. {
  280.     char buf[MAXPATHLEN + 10];
  281.     
  282.     sprintf(buf, "mv: %s", s);
  283.     perror(buf);
  284. }
  285.  
  286. Perror2(s1, s2)
  287.     char *s1, *s2;
  288. {
  289.     char buf[MAXPATHLEN + 20];
  290.  
  291.     sprintf(buf, "mv: %s: %s", s1, s2);
  292.     perror(buf);
  293. }
  294.